import math
import os  # python标准库，不需要安装，用于系统文件操作相关

import cv2  # python非标准库，pip install opencv-python 多媒体处理
import moviepy.video.io.ImageSequenceClip
from PIL import Image  # python非标准库，pip install pillow，图像处理
from moviepy.editor import *


# 图片合成视频
def get_video(image_folder, fps=1, duration=0):
    # 读取图片  图片分辨率要相同
    image_files = [image_folder + '/' + img for img in os.listdir(image_folder) if img.endswith(".jpg")]
    duration = int(math.ceil(duration))
    if duration != 0:
        # 图片合成视频
        video = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, durations=duration)
    else:
        video = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
    return video


# 视频添加bgm
def add_bgm(video_dir, bgm_dir):
    # 读取视频
    video = VideoFileClip(video_dir)
    # 读取bgm，使用0.5倍的音量
    bgm = AudioFileClip(bgm_dir).volumex(0.5)
    # bgm截取（单位秒）
    bgm = bgm.subclip(11, )
    # bgm循环
    end_time = video.duration
    bgm = afx.audio_loop(bgm, duration=video.duration)
    # 视频添加bgm
    return video.set_audio(bgm)


# 调整分辨率（加白边）
def reformat_Image(image_folder):
    max_size = [0, 0]
    image_files = [image_folder + '/' + img for img in os.listdir(image_folder) if img.endswith(".jpg")]
    # 找到图片的最大长度和宽度
    for img_name in image_files:
        img = Image.open(img_name)
        if img.size[0] > max_size[0]:
            max_size[0] = img.size[0]
        if img.size[1] > max_size[1]:
            max_size[1] = img.size[1]
        global size1
        size1 = max_size[0]
        global size2
        size2 = max_size[1]

    # 统一图片分辨率
    num = 1
    for img_name2 in image_files:
        # 新建最大尺寸的background
        background = Image.new('RGBA', (max_size[0], max_size[1]), (255, 255, 255))
        img1 = Image.open(img_name2)
        img1 = img1.convert('RGBA')
        # 使图片居中覆盖background
        parameter1 = (size1 - img1.size[0]) / 2
        parameter2 = (size2 - img1.size[1]) / 2
        background.paste(img1, (int(parameter1), int(parameter2)))
        background.save("./after_imgs/targetImg_" + "{}".format(num) + ".bmp")
        num += 1


def synth_video(frame_dir, audio_path, output_file, fps=1):
    # get_video(image_dir, fps, duration).write_videofile(output_file, threads=16)
    # add_bgm(output_file, audio_path).write_videofile(output_file, threads=16)
    image_to_video(frame_dir, output_file, fps)
    set_music(output_file, audio_path)


def image_to_video(frame_dir, output_file, fps=1):
    '''
    图片合成视频函数
    :param image_path: 图片路径
    :param media_path: 合成视频保存路径
    :return:
    '''
    # 获取图片路径下面的所有图片名称
    image_names = os.listdir(frame_dir)
    # 对提取到的图片名称进行排序
    image_names.sort(key=lambda n: int(n[:-4]))
    # 设置写入格式
    # fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V')
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    # 读取第一个图片获取大小尺寸，因为需要转换成视频的图片大小尺寸是一样的
    image = Image.open(os.path.join(frame_dir, image_names[0]))
    # 初始化媒体写入对象
    media_writer = cv2.VideoWriter(output_file, fourcc, fps, image.size)
    # 遍历图片，将每张图片加入视频当中
    for image_name in image_names:
        im = cv2.imread(os.path.join(frame_dir, image_name))
        media_writer.write(im)
        # print(image_name, '合并完成！')
    # 释放媒体写入对象
    media_writer.release()
    print('无声视频写入完成！')


def set_music(video_path, audio_path):
    '''
    合成视频设置背景音乐函数
    :return:
    '''
    print('开始添加背景音乐！')
    infos = os.path.splitext(video_path)
    output_video1 = infos[0] + "_final" + infos[1]
    if os.path.exists(output_video1):
        os.remove(output_video1)
    videoclip = VideoFileClip(video_path)
    audioclip = AudioFileClip(audio_path)
    new_audioclip = CompositeAudioClip([audioclip])
    videoclip.audio = new_audioclip
    videoclip.write_videofile(output_video1)
    print('背景音乐添加完成！')
